from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from rest_framework.mixins import ListModelMixin, DestroyModelMixin, CreateModelMixin, UpdateModelMixin
from system.serializer.menuserializer import MenuModelSerializer, MenuSerializer, CreateMenuSerializer, \
    UpdateMenuSerializer
from rest_framework.views import APIView
from system import models
from rest_framework.response import Response
from admin.utils.page import Mypage
from rest_framework.filters import SearchFilter


class MenuView(GenericViewSet, ListModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin):
    queryset = models.Menu.objects.filter(is_delete=False, hidden=False, is_menu=True).order_by('menu_sort')
    serializer_class = MenuModelSerializer

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset(), request)
        serializer = self.get_serializer(queryset, many=True)
        tree_dict = {}
        tree_data = []
        try:
            for item in serializer.data:
                tree_dict[item['id']] = item
            for i in tree_dict:
                if tree_dict[i]['pid']:
                    pid = tree_dict[i]['pid']
                    parent = tree_dict[pid]
                    parent.setdefault('children', []).append(tree_dict[i])
                else:
                    tree_dict[i]['path'] = '/' + tree_dict[i]['path']
                    tree_dict[i]['redirect'] = 'noredirect'
                    tree_dict[i]['alwaysShow'] = True
                    tree_data.append(tree_dict[i])  # 父菜单
            results = tree_data
        except KeyError:
            results = serializer.data
        return Response(results)
    def filter_queryset(self, queryset, request):
        l = []
        # print(request.user.roles.all())        # <QuerySet [<Roles: 超级管理员>]>
        for i in queryset:
             # print(i)                        # 系统管理
            for role in i.roles_set.all():     # <QuerySet [<Roles: 超级管理员>, <Roles: 普通用户>, <Roles: 测试>]>
                if role in request.user.roles.all():
                    l.append(i)
                else:
                    continue
        return l


    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object(request)
        serializer = self.get_serializer(instance, data=request.data, partial=partial, context={'request': request})
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        return Response(serializer.data)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_del_object(request)
        for i in instance:
            self.perform_destroy(i)
        return Response(status=status.HTTP_204_NO_CONTENT)

    def get_del_object(self, request):
        id_list = request.data
        menu_list = []
        for id in id_list:
            menu_list.append(models.Menu.objects.filter(pk=id))
        return menu_list

    def perform_destroy(self, instance):
        instance.update(is_delete=True, hidden=True)  # 隐藏

    def get_object(self, request):
        pk = request.data.get('id')
        return models.Menu.objects.filter(pk=pk).first()

    def get_serializer_class(self):
        if self.action == 'list':
            return MenuModelSerializer
        elif self.action == 'create':
            return CreateMenuSerializer
        else:
            return UpdateMenuSerializer


class DeptMenuVew(GenericViewSet, ListModelMixin):
    queryset = models.Menu.objects.filter(is_delete=False).order_by('id')
    serializer_class = MenuSerializer
    pagination_class = Mypage
    filter_backends = [SearchFilter, ]
    search_fields = ['title', 'component']

    def list(self, request, *args, **kwargs):
        pid = request.GET.get('pid')
        queryset = self.filter_queryset(self.get_queryset())
        if pid == None or pid == '0':
            if request.GET.get('search'):
                queryset = queryset
            else:
                queryset = queryset.filter(pid=None)
        else:
            queryset = queryset.filter(pid=pid)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)


class MenuViewSuperior(GenericAPIView, CreateModelMixin):
    queryset = models.Menu.objects.filter(is_delete=False, hidden=False, is_menu=True, pid_id=None).order_by(
        'menu_sort')
    serializer_class = MenuSerializer
    pagination_class = Mypage

    def post(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)







class RoleMenuGetIdList(APIView):
    """
    返回一个列表，
    角色右边菜单选择前的获取点击菜单的id
    如果有父菜单，父菜单和子菜单的id返回
    如果没用，返回请求的参数
    """
    def get(self, request):
        request_id = request.GET.get('id')              # 当前路径的请求参数
        response = []
        menu = models.Menu.objects.filter(pk=request_id).first()      # 当前点击的菜单对象
        if menu.sub_count:
            for i in models.Menu.objects.filter(pid_id=request_id):
                response.append(i.pk)
                if i.sub_count:
                    for y in models.Menu.objects.filter(pid_id=i.pk):
                        response.append(y.pk)
            response.append(int(request_id))
        else:
            response.append(request_id)
        return Response(response)